package com.main;

import java.security.Key;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alipay.sign.RSA;
import com.alipay.util.*;
import org.apache.log4j.Logger;

import com.alipay.config.AlipayConfig;
import com.alipay.config.ZhifuConfig;
import com.itrus.util.sign.RSAWithSoftware;

public class PayService {
	private static Logger logger=Logger.getLogger(PayService.class.getName());
	
	/**提交支付请求*/
	public static void submit(ExtendMap<String,Object> paramMap,HttpServletRequest request, HttpServletResponse response){
		int payType=paramMap.getInt("payType");
		try{
			String sHtmlText="";
			String webSite = ParseConfig.getConfigMap("notify").get("payWebSite");  //网站
			if(payType==1){//支付宝支付
				ExtendMap<String,Object> map=new ExtendMap<String,Object>();
				map.put("service",AlipayConfig.getService(request.getHeader("User-Agent")));
				map.put("partner",ParseConfig.getConfigMap("alipay").getString("partner"));
				map.put("_input_charset",AlipayConfig.input_charset);
				map.put("sign_type",AlipayConfig.sign_type);
//				map.put("sign",ParseConfig.getConfigMap("alipay").getString("seller_id"));
				map.put("notify_url",webSite +"/aliYbNotify.do");
				map.put("return_url",webSite +"/aliTbNotify.do");
				map.put("payment_type",AlipayConfig.payment_type);
				map.put("out_trade_no",paramMap.getString("orderId"));
				map.put("subject",paramMap.getString("orderId"));
				map.put("total_fee",paramMap.getString("orderSum"));
				map.put("seller_id",ParseConfig.getConfigMap("alipay").getString("partner"));
//				map.put("show_url","");
				map.put("subject",paramMap.getString("orderId"));
				map.put("body",paramMap.getString("orderId"));
				sHtmlText = AlipaySubmit.buildRequest(map,"post","确认");
				System.out.println(sHtmlText);
			}else if(payType==2){//微信支付
				sHtmlText="暂未开放微信支付！";
			}else if(payType==3){//智付支付
				ZhifuConfig config=new ZhifuConfig();
				config.order_no=paramMap.getString("orderId");
				config.order_amount=paramMap.getString("orderSum");
				config.product_name=paramMap.getString("orderName");
				config.order_time=UtilDate.getNowDate();
				
			StringBuffer signStr=new StringBuffer();
				
				String bank_code=paramMap.getString("bank_code");
				if(!bank_code.equals("")) signStr.append("bank_code=").append(bank_code).append("&");
				
				signStr.append("input_charset=").append(config.input_charset).append("&");
				signStr.append("interface_version=").append(config.interface_version).append("&");
				signStr.append("merchant_code=").append(config.merchant_code).append("&");
				signStr.append("notify_url=").append(config.notify_url).append("&");
				signStr.append("order_amount=").append(config.order_amount).append("&");
				signStr.append("order_no=").append(config.order_no).append("&");
				signStr.append("order_time=").append(config.order_time).append("&");
				signStr.append("product_name=").append(config.product_name).append("&");
				signStr.append("return_url=").append(config.return_url).append("&");
				signStr.append("service_type=").append(config.service_type);
				String signInfo = signStr.toString();
				String sign=RSAWithSoftware.signByPrivateKey(signInfo,config.RSA_S_PrivateKey);
				
				String bankHtml=bank_code.equals("") ? "" : ("<input type='hidden' name='bank_code' value='"+bank_code+"' />");
				sHtmlText="<body onLoad='document.dinpayForm.submit();'>" +
						"<form name='dinpayForm' method='post' action='https://pay.dinpay.com/gateway?input_charset=UTF-8' target='_self'>" +
						bankHtml +
						"<input type='hidden' name='sign'          value='"+sign+"' />" +
						"<input type='hidden' name='merchant_code' value='"+config.merchant_code+"' />" +
						"<input type='hidden' name='bank_code'     value='"+config.bank_code+"'/>" +
						"<input type='hidden' name='order_no'      value='"+config.order_no+"'/>" +
						"<input type='hidden' name='order_amount'  value='"+config.order_amount+"'/>" +
						"<input type='hidden' name='service_type'  value='"+config.service_type+"'/>" +
						"<input type='hidden' name='pay_type'  value='"+config.pay_type+"'/>" +
						"<input type='hidden' name='input_charset' value='"+config.input_charset+"'/>" +
						"<input type='hidden' name='notify_url'    value='"+config.notify_url+"'>" +
						"<input type='hidden' name='interface_version' value='"+config.interface_version+"'/>" +
						"<input type='hidden' name='sign_type'     value='"+config.sign_type+"'/>" +
						"<input type='hidden' name='order_time'    value='"+config.order_time+"'/>" +
						"<input type='hidden' name='product_name'  value='"+config.product_name+"'/>" +
						"<input Type='hidden' name='client_ip'     value='"+config.client_ip+"'/>" +
						"<input Type='hidden' name='extend_param'  value='"+config.extend_param+"'/>" +
						"<input Type='hidden' name='extra_return_param' value='"+config.extra_return_param+"'/>" +
						"<input Type='hidden' name='product_code'  value='"+config.product_code+"'/>" +
						"<input Type='hidden' name='product_desc'  value='"+config.product_desc+"'/>" +
						"<input Type='hidden' name='product_num'   value='"+config.product_num+"'/>" +
						"<input Type='hidden' name='return_url'    value='"+config.return_url+"'/>" +
						"<input Type='hidden' name='show_url'      value='"+config.show_url+"'/>" +
						"<input Type='hidden' name='redo_flag'     value='"+config.redo_flag+"'/>" +
						"</form></body>";
			}else{
				sHtmlText="无效的支付类型！";
			}
			
			response.getWriter().write("<html>");
			response.getWriter().write("<head>");
			response.getWriter().write("<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'>");
			response.getWriter().write("<title>提交支付信息</title>");
			response.getWriter().write("</head>");
			response.getWriter().write(sHtmlText);
			response.getWriter().write("</html>");
		}catch(Exception e){
			e.printStackTrace();
			logger.error(e.getMessage(),e);
		}
	}
	
	/**支付宝同步通知*/
	public static void aliTbNotify(ExtendMap<String,Object> paramMap,HttpServletRequest request, HttpServletResponse response){
		try{
			ExtendMap<String,Object> logMap=aliVerify(paramMap);
			int i=writeLog(logMap);
			if(i == 1){
				ExtendMap<String,String> notify=ParseConfig.getConfigMap("notify");
				String tburl=notify.getString("tburl");
				response.sendRedirect(tburl.indexOf("?")>0 ? tburl+"&orderId="+logMap.get("order_id") : tburl+"?orderId="+logMap.get("order_id"));
			}

		}catch(Exception e){
			e.printStackTrace();
			logger.error(e.getMessage(),e);
		}
	}


	/**支付宝异步通知*/
	public static void aliYbNotify(ExtendMap<String,Object> paramMap,HttpServletRequest request, HttpServletResponse response){
		try{
			ExtendMap<String,Object> logMap=aliVerify(paramMap);
			logger.info(logMap);
			int i=writeLog(logMap);
			if(i==1){
				ExtendMap<String,String> notify=ParseConfig.getConfigMap("notify");
				String yburl=notify.getString("yburl");
				yburl = yburl.indexOf("?")>0 ? yburl+"&orderId="+logMap.get("order_id") : yburl+"?orderId="+logMap.get("order_id");
				logger.info(yburl);
				HttpClientExecutor.execute(yburl);
//				response.sendRedirect(yburl.indexOf("?")>0 ? yburl+"&orderId="+logMap.get("order_id") : yburl+"?orderId="+logMap.get("order_id"));
			}
		}catch(Exception e){
			e.printStackTrace();
			logger.error(e.getMessage(),e);
		}
	}
	
	/**支付宝支付结果验证*/
	private static ExtendMap<String,Object> aliVerify(ExtendMap<String,Object> paramMap){
		boolean verify_result=AlipayNotify.verify(paramMap);
		
		ExtendMap<String,Object> logMap=new ExtendMap<String,Object>();
		logMap.put("order_id",paramMap.get("out_trade_no"));
		logMap.put("order_name",paramMap.get("subject"));
		logMap.put("order_sum",paramMap.get("total_fee"));
		logMap.put("pay_type",OrderPayTypeEnums.ALIPAY.getValue());
		logMap.put("pay_state",verify_result ? 1 : 2);
		logMap.put("notify_time",paramMap.get("notify_time"));
		logMap.put("remarks",paramMap.toString());
		
		return logMap;
	}
	
	/**智付宝同步通知*/
	public static void zhifuTbNotify(ExtendMap<String,Object> paramMap,HttpServletRequest request, HttpServletResponse response){
		try{
			ExtendMap<String,Object> logMap=zhifuVerify(paramMap);
			int i= writeLog(logMap);
			if( i == 1){
				ExtendMap<String,String> notify=ParseConfig.getConfigMap("notify");
				String tburl=notify.getString("tburl");
				response.sendRedirect(tburl.indexOf("?")>0 ? tburl+"&orderId="+logMap.get("order_id") : tburl+"?orderId="+logMap.get("order_id"));
			}
		}catch(Exception e){
			e.printStackTrace();
			logger.error(e.getMessage(),e);
		}
	}
	
	/**智付异步通知*/
	public static void zhifuYbNotify(ExtendMap<String,Object> paramMap,HttpServletRequest request, HttpServletResponse response){
		try{
			ExtendMap<String,Object> logMap=zhifuVerify(paramMap);
			int i=writeLog(logMap);
			
			if(i==1){
				ExtendMap<String,String> notify=ParseConfig.getConfigMap("notify");
				String yburl=notify.getString("yburl");
				yburl = yburl.indexOf("?")>0 ? yburl+"&orderId="+logMap.get("order_id") : yburl+"?orderId="+logMap.get("order_id");
				logger.info(yburl);
				HttpClientExecutor.execute(yburl);
			}
		}catch(Exception e){
			e.printStackTrace();
			logger.error(e.getMessage(),e);
		}
	}
	
	/**智付支付结果验证*/
	private static ExtendMap<String,Object> zhifuVerify(ExtendMap<String,Object> paramMap) throws Exception{
		StringBuilder signStr=new StringBuilder();

		if(!paramMap.getString("bank_seq_no").equals("")) signStr.append("bank_seq_no=").append(paramMap.get("bank_seq_no")).append("&");
		if(!paramMap.getString("extra_return_param").equals("")) signStr.append("extra_return_param=").append(paramMap.get("extra_return_param")).append("&");
		signStr.append("interface_version=V3.0").append("&");
		signStr.append("merchant_code=").append(paramMap.get("merchant_code")).append("&");
		if(!paramMap.getString("notify_id").equals("")){
			signStr.append("notify_id=").append(paramMap.get("notify_id")).append("&notify_type=").append(paramMap.get("notify_type")).append("&");
		}
		signStr.append("order_amount=").append(paramMap.get("order_amount")).append("&");
		signStr.append("order_no=").append(paramMap.get("order_no")).append("&");
		signStr.append("order_time=").append(paramMap.get("order_time")).append("&");
		signStr.append("trade_no=").append(paramMap.get("trade_no")).append("&");
		signStr.append("trade_status=").append(paramMap.get("trade_status")).append("&");
		if(!paramMap.getString("trade_time").equals("")) signStr.append("trade_time=").append(paramMap.get("trade_time")).append("&");
		
		String signInfo=signStr.substring(0,signStr.length()-1);
		String dinpaySign=paramMap.getString("sign");
		boolean verify_result=RSAWithSoftware.validateSignByPublicKey(signInfo,ZhifuConfig.RSA_S_PublicKey,dinpaySign);
		
		ExtendMap<String,Object> logMap=new ExtendMap<String,Object>();
		logMap.put("order_id",paramMap.get("order_no"));
		logMap.put("order_name","");
		logMap.put("order_sum",paramMap.get("order_amount"));
		logMap.put("pay_type",OrderPayTypeEnums.DINPAY.getValue());
		logMap.put("pay_state",verify_result ? 1 : 2);
		logMap.put("notify_time",UtilDate.getNowDate());
		logMap.put("remarks",paramMap.toString());
		
		return logMap;
	}
	
	/**输出订单支付结果到数据库*/
	public static int writeLog(ExtendMap<String,Object> logMap){
		int result=0;
		ExtendMap<String,String> database=ParseConfig.getConfigMap("database");
		Connection conn=null;
		try{
			Class.forName(database.getString("driverClassName"));
			conn=DriverManager.getConnection(database.getString("url"),database.getString("username"),database.getString("password"));
			
			PreparedStatement ps=conn.prepareStatement("select pay_state from t_pay_log where order_id=?");
			ps.setObject(1,logMap.get("order_id"));
			ResultSet rs=ps.executeQuery();
			if(rs.next()){
				logMap.put("pay_state",rs.getObject("pay_state"));
			}else{
				ps=conn.prepareStatement("insert into t_pay_log(order_id,order_name,order_sum,pay_type,pay_state,notify_time,remarks) values(?,?,?,?,?,?,?)");
				ps.setObject(1,logMap.get("order_id"));
				ps.setObject(2,logMap.get("order_name"));
				ps.setObject(3,logMap.get("order_sum"));
				ps.setObject(4,logMap.get("pay_type"));
				ps.setObject(5,logMap.get("pay_state"));
				ps.setObject(6,logMap.get("notify_time"));
				ps.setObject(7,logMap.get("remarks"));
				ps.executeUpdate();
				result=1;
			}
		}catch(Exception e){
			result=1;
			logger.info(logMap);
//			e.printStackTrace();
//			logger.error(e.getMessage(),e);
		}finally{
			try{conn.close();}catch(Exception e){}
		}
		return result;
	}
}